K I S S User Guide Starting Kiss ------------- Kiss supports a lot of flags. Try "[brg]kiss -h" if you want to see the list. The executable that you want to start is either "bkiss", "gkiss" or "rkiss", I suggest "rkiss" if you have all of them (you have now, since you've unpacked the archive). The "bkiss" version ("b" for "bare") has no line editing facilities, but is the smallest - so it's ideal for a rescue disk. The "gkiss" program has getline support, it has line editing. The "rkiss" finally has line editing and filename completion. Supported flags by all the Kiss programs are, e.g., "-c command" to run a command, or "file [file..]" to load scripts. Mostly, you'll want Kiss just started in interactive mode, without any flags. To get a feel for how things work, try "help". If too much info scrolls off the screen, try "help | more". That will show all the built-in commands and an overview of relevant environment settings. A handy thing to keep in mind: most built-in commands recognize the "-h" flag. If you want to know how the built-in "ls" works, try "ls -h". The command parser ------------------ Kiss has an input parser which works as follows. I'm just describing some of the highlights here, so that you know. The input consists of one or more lines. You can terminate Kiss by stopping the input: either send an EOF character (^D) or type "exit" (or, "exit 3" if you want exit status 3). See the info which the "help" command provides about "exit". (Note: the getline version requires you to type ^D twice to exit, it's some quirk.) Each line consists of statements, separated by pipe tokens and terminated by a newline token. Which means that the command will be interpreted as soon as you hit enter (what did you expect). The pipe tokens work in the normal fashion: "a | b | c | d" will start four programs, "a" to "d", where each next program receives on its standard input the output of the previous program. The output of "d" (if any) goes to the screen, the input of "a" (if any) comes from the keyboard. Kiss doesn't understand piping of other streams than stdin and stderr. Standard-error messages will always appear on screen. Furthermore, the parser understands the "&" character when it appears as the last thing on the input line. Note that "&" marks may not appear elsewhere. Besides the newline-terminator, Kiss knows about the ";" character. E.g., "ls ; ls" will run two "ls" commands for you. The ";" character is handy in aliases (described later), but in interactive mode it's just like typing a newline. Incidentally, this means that if you want a 'real' semicolon (e.g., as an argument to the "find" program), you must `protect' it by quoting it; as in: prompt> find / -exec ls {} ';' Quoting special characters is always done with single or double quotes, the same reasoning holds for pipe tokens "|" and redirections "<" etc.. A statement (i.e., info between the "|" marks or just the strings when no piping is needed) is either the `recall' command or a `real' command. The recall command is very handy: those familiar with Tcsh surely know it. It recalls a command from the "history list". E.g., "!d" re-runs the last command that starts with "d". Another history-related command is "history", which shows what your previous commands are. Try "history | more" if the list is getting long. If you find typing "history" too much, try "alias his history" and then "his | more". Or even: "alias mhis 'history | more'" , and then "mhis". Commands which don't recall previously entered commands may be followed by "< file" and/or "> file" or ">> file", forcing redirection of stdin or stdout to a file. Kiss doesn't support redirection of stderr. In the end, commands are just strings. Kiss knows four types of strings: a. Simple strings are just what they are, e.g. names of program files. Simple strings are subject to expansion of wildcards (e.g., *.c becomes a lot of strings) etc. b. Quoted strings are enclosed by " or '. Such strings aren't subject to expansion. This is the way to protect `special' characters like pipe tokens, semicolons or "<" and ">". c. Backquoted strings are enclosed by `. These are substituted with the output of a program; e.g. "echo `ls`". d. Variables are in the form $STUFF. Note that Kiss only knows of variables which are named in upper case. Also note that Kiss doesn't understand variable names in the form ${STUFF}. Strings which contain "~/" are rewritten so that the tilde is expanded to the user's home directory. E.g, when you type "cd ~/bin" then you change-dir to "$HOME/bin". Environment access ------------------ Kiss has four commands which access the environment. a. "printenv" shows the environment in a series of lines "VAR=value". You can also look for only one environment string, e.g. "printenv PATH". b. "setenv VAR value" sets the environment variable "VAR" to "value. E.g., prompt> setenv PATH $PATH:/usr/local/bin adds "/usr/local/bin" to the search path. c. The syntax "VAR=value" is a synonym for "setenv". Spaces are allowed; "VAR = value" is the same as "VAR=value". d. The command "unsetenv VAR" removes the "VAR" from the environment. Of course, you can type "$VAR" to get the value of a variable, as in prompt> echo $PATH Relevant environment variables are: a. $PATH is of course the search-path for programs. A handy command here is "where", e.g., try "where ls". It will show that "ls" is a built-in command but also resides in "/bin/ls". b. $HOME is set by Kiss to the user's home directory. c. $PWD is maintained by Kiss and always holds the current working directory. The command "pwd" prints it. d. $SHELL is the name of the shell interpreter, e.g. "/usr/local/bin/kiss". e. $SHLVL is the shell level: initially "1". As Kiss forks to start programs, $SHLVL is incremented. This variable is mainly for internal use. f. $UID is the numerical user ID, $USER is the user name (when available). g. $PROMPT tells Kiss what to display as the input prompt. You can put special characters in the setting: %p gives the current working directory, %u gives the username, %n gives a newline. The default $PROMPT is "[%u] %p > ", which gives something like "[username] /tmp > " as the prompt. h. $$ is the shell's process ID. i. $? is the last command's exit status. j. $! is the last command's process ID. Aliases ------- Kiss understands a special command called "alias", to set up an alias for a command. Example: prompt> alias d ls -Fla prompt> d # this runs "ls -Fla" prompt> d /tmp # this runs "ls -Fla /tmp" If you postfix any arguments to an alias (as in "d /tmp"), then those arguments will be postfixed to the expanded command (giving "ls -Fla /tmp"). You can mention arguments in aliases, use $1, $2 etcetera. E.g.: prompt> alias dx 'ls -l *.$1' prompt> dx c # this runs "ls -l *.c" Here you need to mention "$1" explicitely because you want that argument to be appended to "ls -l *." without spaces in between. This way you control where arguments exactly appear in an alias. Another handy alias for X users: prompt> alias xvi 'xterm -e vi $1 &' prompt> xvi somefile # runs xterm -e vi somefile & Here you need to mention "$1" explicitely because following the argument you want the "&" character. The "alias" command can also list aliases (when invoked without arguments) or a particular alias (when invoked with one argument). Once you invoke "alias" with two or more arguments, you're defining a new alias or redefining an old one. I call aliases which invoke more than one command `chained aliases'. E.g.: prompt> alias go 'a ; b' prompt> go # this runs first "a", then "b" Kiss only understands simple alias chaining, so beware. Some restrictions are: a. The commands in a chained alias must be separated by a ; in spaces. So: prompt> alias go 'a;b' # won't work, you need 'a ; b' You really need the space before AND after the semicolon. This requirement is btw. only true in aliases, the semicolon doesn't need spaces around it when you enter it interactively. (It's not a perfect world..) b. Chained aliases may only consist of two commands, not more. E.g.: prompt> alias go 'a ; b ; c' # won't work, three commands To run three commands via an alias, you need an intermediate alias: prompt> alias go 'a ; go_1' prompt> alias go_1 'b ; c' prompt> go # now this runs a, b and then c c. The second command in an alias isn't passed arguments, you just can run it `bare'. Startup files ------------- Kiss tries to load two startup files, one system-wide resource and one user-owned resource. The files are: a. /etc/kiss.rc : system-wide file b. ~/.kissrc : user-owned file You can put anything in the startup files, including "cd" commands, "echo", or whatever. The files are however typically used for auto-loading aliases. Here's a favorite of mine, which you can put into your ~/.kissrc: # my favorite editor EDITOR = jove # how to re-read ~/.kissrc alias reload source ~/.kissrc # how to edit ~/.kissrc and re-read it immediately alias ek '$EDITOR ~/.kissrc ; reload' The built-in commands --------------------- Here follows a brief description of the built-in commands. Most of them will work as expected; I'm just focusing on the differences. A handy command to find out whether a command is a built-in is "where"; e.g., "where mount" will show where an external "mount" program resides and that "mount" is an internal command. If you prefer to start the external command instead of the internal one, just type the full name (say "/sbin/mount") instead of just "mount". "cat": Doesn't support buffer sizes or what else you need. Just prints stdin or a file to stdout. "chmod": You can use here mode strings like "a+x" (for all: add execute bit), or octal numbers (644 for owner: r/w, group: r, others: r). The mode strings however don't know about sticky or setuid bits, just r/w/x. Use octal modes to set or clear s-bits. "chown": Just changes the owner, you can't change both owner and group with one command. Use "chgrp" to change group ownership. "cp": Is pretty clever, copies files while preserving `holes'. This means unfortunately that "cp" is slow. Needs rewriting. Furthermore, "cp" only copies _files_, not pipes or devices. Use "mknod" to create devices. "cp" does know about symlinks though, it will copy links if you give it the "-d" flag. Also, "cp" may not synthesize destination pathnames as you're used to. I never figured out the original "cp" anyway. "grep": Just a subset of the real "grep", though it understands true regular expressions. Only supports "-i" (ignore case) and "-v" (show non-matching lines) flags. "kill": Doesn't support symbolic names for signals (e.g. "-HUP"). Just the numbers. "ln": Always requires that the link to create doesn't exist, you cannot overwrite files with new links. Not even with the "-f" flag. The "ln" command interprets its "-f" flag a bit off: for me it means "create a link even if it points nowhere". Hm. "ls": Output in columns is sorted left-to-right, while the original "ls" sorts top-to-bottom. I don't intend on fixing that. Also, dates and times are displayed a bit non-standard with "ls -l". "mknod": Always creates pipes or devices with octal mode 644. There's no "--mode" flag. Use "chmod" to adjust the mode. "more": No page-back commands, and you must hit ENTER after each input. Always pauses after 23 lines of output. Doesn't recognize too long lines. "mount": Doesn't update /etc/mtab, so you can't get a listing of what's mounted and what not. Also doesn't inspect /etc/fstab so that you never can mount all. Doesn't support read/only mounting. "setenv" and its alias "VAR=value": Only knows about variables in upper case. You can't make variables in lower case. "source": Doesn't check `circular' sourcing, you could e.g. source file "a" which contains "source b", so that "b" is sourced, but if "b" sources "a" again then you have an endless loop. "touch": Only sets file times to the current time. "wc": The word counting is a bit off, I couldn't figure out what the orginal "wc" considers one `word'. The line and character counts are ok though. Signal handling --------------- Kiss will try to stay alive as long as possible. I know that the program isn't perfect: if it is signalled with a segmentation fault, it tries to reload. I know that this is non-standard, but I want to provide some interpreter access when things go haywire. Other signals which are caught by Kiss are: a. 10 and 12; SIGUSR1 and SIGUSR2. Kiss will try to reload when you send it this signal. E.g., try prompt> kill -10 $$ b. Signal 2 (SIGINT, sent when you type ^C) is by default ignored. Start Kiss with the "-C" flag if you want Kiss to abort with ^C. c. Other signals have the default action; e.g., signal 15 will kill Kiss. (Signal 9 will too ;-).